78 lines · 3.2 KB
1 ---
2 import Repo from '../../../../layouts/Repo.astro';
3 import { apiGet } from '../../../../lib/api';
4
5 const { owner, repo } = Astro.params;
6 const cookie = Astro.request.headers.get('cookie') || '';
7 const url = new URL(Astro.request.url);
8 const state = url.searchParams.get('state') || 'open';
9
10 let mrs: any[] = [];
11 let error = '';
12
13 try {
14 mrs = await apiGet(`/api/repos/${owner}/${repo}/merge-requests?state=${state}`, cookie);
15 } catch (e: any) {
16 error = e.message;
17 }
18 ---
19
20 <Repo owner={owner!} repo={repo!}>
21 <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
22 <div style="display: flex; gap: 8px;">
23 <a href={`/${owner}/${repo}/merge-requests?state=open`}
24 class="btn" style={state === 'open' ? 'background: var(--accent); border-color: var(--accent); color: #fff;' : ''}>
25 Open
26 </a>
27 <a href={`/${owner}/${repo}/merge-requests?state=merged`}
28 class="btn" style={state === 'merged' ? 'background: var(--accent); border-color: var(--accent); color: #fff;' : ''}>
29 Merged
30 </a>
31 <a href={`/${owner}/${repo}/merge-requests?state=closed`}
32 class="btn" style={state === 'closed' ? 'background: var(--accent); border-color: var(--accent); color: #fff;' : ''}>
33 Closed
34 </a>
35 </div>
36 <a href={`/${owner}/${repo}/merge-requests/new`} class="btn btn-primary">New merge request</a>
37 </div>
38
39 {error && <div class="flash-error">{error}</div>}
40
41 <div>
42 {mrs.length === 0 && (
43 <p style="text-align: center; padding: 48px 0; color: var(--text-muted);">
44 No {state} merge requests.
45 </p>
46 )}
47 {mrs.map((mr: any) => (
48 <a href={`/${owner}/${repo}/merge-requests/${mr.number}`}
49 style="display: block; padding: 12px 16px; border: 1px solid var(--border); border-bottom: none; background: var(--bg-secondary); text-decoration: none; font-size: 0.875rem;"
50 class="mr-row">
51 <div style="display: flex; justify-content: space-between; align-items: center;">
52 <div>
53 <span style="font-weight: 600; color: var(--text);">{mr.title}</span>
54 <span style="color: var(--text-muted);"> #{mr.number}</span>
55 </div>
56 <span style={`font-size: 0.75rem; padding: 2px 8px; border-radius: 12px; border: 1px solid; ${
57 mr.state === 'open' ? 'color: var(--state-open); border-color: var(--state-open);'
58 : mr.state === 'merged' ? 'color: var(--state-merged); border-color: var(--state-merged);'
59 : 'color: var(--state-closed); border-color: var(--state-closed);'
60 }`}>
61 {mr.state}
62 </span>
63 </div>
64 <div style="color: var(--text-muted); font-size: 0.8125rem; margin-top: 4px;">
65 opened by {mr.author_username} &middot; {mr.source_branch} → {mr.target_branch}
66 </div>
67 </a>
68 ))}
69 </div>
70 </Repo>
71
72 <style>
73 .mr-row:first-of-type { border-radius: var(--radius) var(--radius) 0 0; }
74 .mr-row:last-of-type { border-bottom: 1px solid var(--border) !important; border-radius: 0 0 var(--radius) var(--radius); }
75 .mr-row:only-of-type { border-radius: var(--radius); border-bottom: 1px solid var(--border) !important; }
76 .mr-row:hover { background: var(--bg-tertiary) !important; }
77 </style>
78